package com.siebre.picclife.asynctask.service.support;

import java.util.List;

import org.hibernate.SessionFactory;
import org.hibernate.criterion.Property;
import org.springframework.transaction.annotation.Transactional;

import com.siebre.picclife.asynctask.model.Task;
import com.siebre.picclife.asynctask.model.TaskStatus;
import com.siebre.picclife.asynctask.model.impl.TaskEntity;
import com.siebre.picclife.asynctask.service.TaskRepository;

/**
 * 
 * @author ZhangChi
 * @since 2015年4月2日
 */
public class DatabaseTaskRepository implements TaskRepository {
	
	private SessionFactory sessionFactory;
	
	public DatabaseTaskRepository(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	@Transactional
	public void save(Task task) {
		sessionFactory.getCurrentSession().saveOrUpdate(task);
	}

	@Transactional(readOnly = true)
	public Task findOne(long id) {
		return (Task) sessionFactory.getCurrentSession().load(TaskEntity.class, id);
	}

	@Transactional(readOnly = true)
	@SuppressWarnings("unchecked")
	public List<Task> findByArgument(String descriptor) {
		return sessionFactory.getCurrentSession()
				.createCriteria(Task.class)
				.add(Property.forName("argument").eq(descriptor))
				.list();
	}

	@Transactional(readOnly = true)
	@SuppressWarnings("unchecked")
	public List<Task> findNewTasks(int pageIndex, int pageSize) {
		return sessionFactory.getCurrentSession()
				.createCriteria(Task.class)
				.add(Property.forName("status").eq(TaskStatus.NEW))
				.setFirstResult(pageIndex * pageSize)
				.setMaxResults(pageSize)
				.list();
	}

	@Transactional(readOnly = true)
	@SuppressWarnings("unchecked")
	public List<Task> findFailedTasks(int pageIndex, int pageSize) {
		return sessionFactory.getCurrentSession()
				.createCriteria(Task.class)
				.add(Property.forName("status").eq(TaskStatus.FAILED))
				.setFirstResult(pageIndex * pageSize)
				.setMaxResults(pageSize)
				.list();
	}

//	@SuppressWarnings("unchecked")
//	public List<Task> findCorruptedTasks(Range<Date> createdRange, String taskType, int pageIndex, int pageSize) {
//		return sessionFactory.getCurrentSession()
//				.createCriteria(Task.class)
//				.add(Property.forName("createdOn").between(createdRange.lowerEndpoint(), createdRange.upperEndpoint()))
//				.add(Property.forName("type").eq(taskType))
//				.setFirstResult(pageIndex * pageSize)
//				.setMaxResults(pageSize)
//				.list();
//	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<Task> findProcessingTasks(int pageIndex, int pageSize) {
		return sessionFactory.getCurrentSession()
				.createCriteria(Task.class)
				.add(Property.forName("status").eq(TaskStatus.PROCESSING))
				.setFirstResult(pageIndex * pageSize)
				.setMaxResults(pageSize)
				.list();
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<Task> findProcessingTasks(String processor, 
			int pageIndex, int pageSize) {
		return sessionFactory.getCurrentSession()
				.createCriteria(Task.class)
				.add(Property.forName("status").eq(TaskStatus.PROCESSING))
				.add(Property.forName("processor").eq(processor))
				.setFirstResult(pageIndex * pageSize)
				.setMaxResults(pageSize)
				.list();
	}

//	@SuppressWarnings("unchecked")
//	public List<Task> find(Specification<Task> spec, int pageIndex, int pageSize) {
//		return sessionFactory.getCurrentSession()
//				.createCriteria(Task.class)
//				.add(spec.toCriterion())
//				.setFirstResult(pageIndex * pageSize)
//				.setMaxResults(pageSize)
//				.list();
//	}

	@Transactional
	public void deleteAll() {
		sessionFactory.getCurrentSession()
			.createQuery("delete from " + Task.class.getName())
			.executeUpdate();
	}
}
